/********************************************************************************
* @File name: stepmotor.c
* @Author: Loganx
* @Gitee: https://gitee.com/loganxiang/lgxsmartcar
* @Version: 1.0(2025-10-09)
* @Description: STC32G单片机步进电机驱动
********************************************************************************
* 本软件使用了STC的STC32G官方库
********************************************************************************/
#include "Lib/Config.h"
#include "Lib/STC32G_GPIO.h"
#include "stepmotor.h"

unsigned char code StepMotorPhase[] = {0x10,0x30,0x20,0x60,0x40,0xC0,0x80,0x90};

unsigned char StepMotorCommand;
unsigned char StepMotorDirection;
unsigned char StepMotorSpeed;
unsigned int StepMotorAngle;
unsigned int StepMotorPulse;

void StepMotorInit(void){
	GPIO_InitTypeDef gpio;
	
	gpio.Mode = GPIO_OUT_PP;
	gpio.Pin = GPIO_Pin_HIGH;
	
	GPIO_Inilize(GPIO_P1,&gpio);
	
	StepMotorCommand = STEP_MOTOR_STOP;
	StepMotorDirection = STEP_MOTOR_FORWARD;
	StepMotorSpeed = 4;
}

void StepMotorSetSpeed(uint8 rpm){
	StepMotorSpeed = rpm;
}
void StepMotorForward(void){
	StepMotorDirection = STEP_MOTOR_FORWARD;
	StepMotorCommand = STEP_MOTOR_START;
}
void StepMotorReverse(void){
	StepMotorDirection = STEP_MOTOR_REVERSE;
	StepMotorCommand = STEP_MOTOR_START;
}
void StepMotorStop(void){
	StepMotorCommand = STEP_MOTOR_STOP;
}

//0 - 32
void StepMotorSetAngle(uint16 angle){
	int32 diff_angle;
	
	diff_angle = angle - StepMotorAngle;
	if(diff_angle < 0)
		diff_angle += 4096;
	if(diff_angle > 2048){
		StepMotorDirection = STEP_MOTOR_REVERSE;
		StepMotorPulse = (uint16)(4096 - diff_angle);
	}
	else{
		StepMotorDirection = STEP_MOTOR_FORWARD;
		StepMotorPulse = (uint16)(diff_angle);
	}
}

void StepMotorAngleCalibrate(void){
	StepMotorAngle = 0;
}

//Systick callback 1ms
void SystickCallbackStepMotor(void){
	static unsigned char i=0,j=0;
	
	if(StepMotorCommand == STEP_MOTOR_START || StepMotorPulse > 0 ){
		if(++i >= StepMotorSpeed){
			i = 0;
			if(++j >= 8)
				j = 0;
			if(StepMotorDirection == STEP_MOTOR_FORWARD){
				STEP_MOTOR_PORT = StepMotorPhase[j];
				StepMotorAngle++;
			}
			if(StepMotorDirection == STEP_MOTOR_REVERSE){
				STEP_MOTOR_PORT = StepMotorPhase[7 - j];
				StepMotorAngle--;
			}
			if(StepMotorPulse > 0)
				StepMotorPulse--;
		}
	}
	else{
		STEP_MOTOR_PORT = 0x00;
	}
}